package top.lixunda.commerce.common.core.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.sun.istack.internal.NotNull;
import lombok.Getter;
import lombok.ToString;
import top.lixunda.commerce.common.core.function.ThreeConsumer;

import java.util.function.Consumer;


/**
 * @author LiXunda
 * @version time:2019/8/4 11:24
 */
@SuppressWarnings("ALL")
@Getter
@ToString
public class MessageObject<T> {

    /**
     * 执行成功
     */
    public static final int CODE_OK = 200;

    /**
     * 普通错误
     */
    public static final int CODE_ERROR = 400;

    /**
     * 未登录
     */
    public static final int CODE_NOT_LOGIN = 401;

    /**
     * 权限不足
     */
    public static final int CODE_DENY_ACCESS = 402;

    /**
     * 参数错误
     */
    public static final int CODE_ERROR_PARAMETER = 410;

    /**
     * 状态码
     * 1xx 临时响应
     * 2xx 成功
     * 3xx 重定向
     * 4xx 请求错误，客户端请求或参数错误
     * 5xx 服务器错误
     * x51-x99 通用异常占用，自定义异常尽量使用x01-x50
     */
    private int code;

    /**
     * 请求描述消息
     */
    private String msg;

    /**
     * 泛型数据对象
     */
    private T object;

    public MessageObject() {
        this.code = CODE_OK;
        this.msg = "操作成功";
    }

    public MessageObject<T> setCode(int code) {
        this.code = code;
        return this;
    }

    public MessageObject<T> setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public MessageObject<T> setObject(T object) {
        this.object = object;
        return this;
    }

    @JsonIgnore
    public static <T> MessageObject<T> success(@NotNull String msg, T object) {
        return newInstance().setCode(200).setMsg(msg).setObject(object);
    }

    @JsonIgnore
    public static MessageObject<Object> success(@NotNull String msg) {
        return success(msg, null);
    }

    @JsonIgnore
    public static <T> MessageObject<T> success(Class<T> tClass, @NotNull String msg) {
        return success(msg, null);
    }

    @JsonIgnore
    public static <T> MessageObject<T> success(T object) {
        return success("操作成功", object);
    }

    @JsonIgnore
    public static <T> MessageObject<T> error(@NotNull String msg, T object) {
        return newInstance().setCode(400).setMsg(msg).setObject(object);
    }

    @JsonIgnore
    public static MessageObject<Object> error(@NotNull String msg) {
        return error(msg, null);
    }

    @JsonIgnore
    public static <T> MessageObject<T> error(Class<T> tClass, @NotNull String msg) {
        return error(msg, null);
    }

    @JsonIgnore
    public static MessageObject newInstance() {
        return new MessageObject();
    }

    @JsonIgnore
    public static <T> MessageObject<T> newInstance(Class<T> tClass) {
        return new MessageObject();
    }

    @JsonIgnore
    public boolean isSuccess(){
        return this.getCode() == MessageObject.CODE_OK;
    }

    @JsonIgnore
    public boolean isNotSuccess(){
        return !isSuccess();
    }

    @JsonIgnore
    public MessageObject<T> ifSuccess(Consumer<T> consumer) {
        if (this.getCode() == MessageObject.CODE_OK && consumer != null) {
            consumer.accept(this.getObject());
        }
        return this;
    }

    @JsonIgnore
    public MessageObject<T> ifError(ThreeConsumer<Integer, String, T> consumer) {
        if (this.getCode() != MessageObject.CODE_OK && consumer != null) {
            consumer.accept(this.getCode(), this.getMsg(), this.getObject());
        }
        return this;
    }

    @JsonIgnore
    public MessageObject<T> dealWith(ThreeConsumer<Integer, String, T> consumer) {
        if (consumer != null) {
            consumer.accept(this.getCode(), this.getMsg(), this.getObject());
        }
        return this;
    }

}
